home *** CD-ROM | disk | FTP | other *** search
- /* ALCmd.M */
-
- OPT MODULE
- OPT EXPORT
-
- /* Module to process commands to the AList mailing list server */
-
- MODULE 'other/alconfig'
- MODULE 'other/aladd'
- MODULE 'other/alpost'
-
-
- DEF config_list:PTR TO config_node, hostname:PTR TO CHAR, no_from
- /* From aladd.m */
- DEF temp_file:PTR TO CHAR
- /* From alconfig */
- DEF alternate_cmd:PTR TO CHAR
-
- /*
- * Perform one or more commands, as specified by the chained string 'str'.
- */
- PROC do_command (str:PTR TO CHAR)
- DEF from:PTR TO CHAR, to:PTR TO CHAR, list:PTR TO config_node, tmp:PTR TO config_node, s:PTR TO CHAR
- DEF s2:PTR TO CHAR, x, y
-
- to := str
- list := find_list (to)
- from := str := Next (str)
- str := Next (str)
-
- WHILE (is_empty (str) = FALSE)
- str := Next (str)
- ENDWHILE
-
- IF (str = NIL) THEN RETURN /* Don't do a Next (NIL)! */
-
- clear_tmp_file()
- s := String (75)
- IF (no_from OR alternate_cmd)
- StringF (s, 'From: AList@\s\n\n', hostname)
- add_tmp_file (s)
- ENDIF
-
- WHILE (str := Next (str))
- StrCopy (s, str)
- UpperStr (s)
- IF (StrCmp (s, 'HELP', 4))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
- add_tmp_file ('\n')
- add_tmp_help (TrimStr (str+4))
- ELSEIF (StrCmp (s, 'INDEX', 5))
- add_tmp_file ('\nResponse to command\n>>INDEX\n\n')
- tmp := config_list
- y := 0
- IF (tmp) THEN add_tmp_file ('Visible lists:') ELSE add_tmp_file ('No visible lists.\n\n')
- WHILE (tmp)
- IF (y = 0) THEN y := 1
- IF ((tmp.flags AND CNF_INVISIBLE) = 0)
- y := 2
- StringF (s, '\n\s[15]\t \s\n', tmp.name, IF (tmp.sdesc) THEN tmp.sdesc ELSE '')
- add_tmp_file (s)
- tmp := tmp.next
- ENDIF
- ENDWHILE
- IF (y = 1) THEN add_tmp_file ('No visible lists.\n\n')
- ELSEIF (StrCmp (s, 'LIST', 4))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- s2 := TrimStr (str+4)
- y := 0
- IF (IF (s2 = -1) THEN FALSE ELSE (s2[0] > 32))
- StrCopy (s, s2, StrLen (s2) - 1)
- y := 1
- ENDIF
-
- tmp := config_list; x := 0
- WHILE (tmp)
- IF ((y = 0) OR ((tmp.flags AND CNF_INVISIBLE) = 0) )
- IF (on_list (s, tmp.users, (tmp.flags AND CNF_CMP_DOMAIN)))
- x := 1
- StringF (s, '\s[15]\t \s\n', tmp.name, IF (tmp.sdesc) THEN tmp.sdesc ELSE '')
- add_tmp_file (s)
- ENDIF
- ENDIF
- tmp := tmp.next
- ENDWHILE
-
- IF (x = 0)
- IF (y = 0)
- add_tmp_file ('You are not on any lists at this site.\nYour address is "')
- add_tmp_file (s)
- add_tmp_file ('".\n')
- ELSE
- add_tmp_file (s)
- add_tmp_file (' is not on any visible lists at this site.\n')
- ENDIF
- ENDIF
- ELSEIF (StrCmp (s, 'WHO', 3))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- IF (InStr (s, '@') = -1) AND (InStr (s, '!') = -1)
- /* localhost */
- StrAdd (s, '@')
- StrAdd (s, hostname)
- ENDIF
-
- IF (str[4] < 33) /* No list */
- tmp := list
- ELSE
- s2 := String (StrLen (str)-5)
- StrCopy (s2, str+4)
- tmp := find_list (s2)
- DisposeLink (s2)
- ENDIF
- IF (tmp = NIL)
- add_tmp_file ('Requested list not found.\n')
- JUMP do_next_cmd
- ENDIF
-
- IF (tmp.flags AND CNF_MOD_WHO_SELF)
- IF (on_list (s, tmp.users, (tmp.flags AND CNF_CMP_DOMAIN)) = FALSE)
- add_tmp_file ('Only members of that list may obtain a list of subscribed users.\n')
- JUMP do_next_cmd
- ENDIF
- ELSEIF (tmp.flags AND CNF_MOD_WHO_OWN)
- s2 := String (80)
- StrCopy (s2, tmp.owner)
- IF (tmp.flags AND CNF_CMP_DOMAIN)
- domain_only (s2)
- domain_only (s)
- ENDIF
- IF (StrCmp (s, s2) = FALSE)
- add_tmp_file ('Only the owner of that list may obtain a list of subscribed users.\n')
- DisposeLink (s2)
- JUMP do_next_cmd
- ENDIF
- DisposeLink (s2)
- ENDIF
-
- s2 := tmp.users
- add_tmp_file ('Members of list "')
- add_tmp_file (tmp.name)
- add_tmp_file ('":')
- WHILE (s2)
- add_tmp_file ('\n\t')
- add_tmp_file (s2)
- s2 := Next (s2)
- ENDWHILE
- add_tmp_file ('\n')
- ELSEIF (StrCmp (s, 'ADD', 3))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- s2 := String (16)
- IF (list) THEN StrCopy (s2, list.name)
- get_cmd_args (str+3, s2, s)
- add_user (s, s2)
- DisposeLink (s2)
- ELSEIF (StrCmp (s, 'DELETE', 6))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- s2 := String (16)
- IF (list) THEN StrCopy (s2, list.name)
- get_cmd_args (str+6, s2, s)
- remove_user (s, s2)
- DisposeLink (s2)
- ELSEIF (StrCmp (s, 'SUBSCRIBE', 9))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- s2 := String (16)
- IF (list) THEN StrCopy (s2, list.name)
- get_cmd_args (str+9, s2, s)
- add_user (s, s2)
- DisposeLink (s2)
- ELSEIF (StrCmp (s, 'UNSUBSCRIBE', 11))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
-
- StrCopy (s, from)
- s2 := String (16)
- IF (list) THEN StrCopy (s2, list.name)
- get_cmd_args (str+11, s2, s)
- remove_user (s, s2)
- DisposeLink (s2)
- ELSEIF (StrCmp (s, 'END', 3))
- add_tmp_file ('\nResponse to command\n>>END\nCommand processing ending.\n\n')
- str := NIL /* Break the loop! */
- ELSEIF (StrCmp (s, 'INFO', 4))
- add_tmp_file ('\nResponse to command\n>>')
- add_tmp_file (str)
- add_tmp_file ('\n\n')
-
- s2 := NIL
- IF (s[4])
- x := 4
- WHILE (IF s[x] THEN (s[x] < 33) OR (s[x] > 125) ELSE FALSE)
- INC x
- ENDWHILE
- IF (s[x])
- s2 := String (StrLen (str+x)-1)
- StrCopy (s2, str+x)
- ENDIF
- ENDIF
- IF (s2 = NIL)
- IF (list)
- tmp := list
- ELSE
- add_tmp_file ('Which list do you want the description of?\n\n')
- JUMP do_next_cmd
- ENDIF
- ELSE
- tmp := config_list
- WHILE (IF (tmp) THEN (StrCmp (tmp.name, s2) = NIL) ELSE FALSE)
- tmp:= tmp.next
- ENDWHILE
- DisposeLink (s2)
- IF (tmp = NIL)
- add_tmp_file ('Specified list not found.\n\n')
- JUMP do_next_cmd
- ENDIF
- ENDIF
-
- IF (tmp.ldesc = NIL)
- add_tmp_file ('There is no description associated with that list.\n\n')
- ELSE
- DisposeLink (s2)
- s2 := tmp.ldesc
- WHILE (s2)
- add_tmp_file (s2)
- s2 := Next (s2)
- ENDWHILE
- add_tmp_file ('\n')
- ENDIF
- ELSE
- IF (str[0] > 32)
- add_tmp_file ('\nUnknown command: ')
- add_tmp_file (str)
- ENDIF
- ENDIF
- do_next_cmd:
- ENDWHILE
-
- DisposeLink (s)
- add_tmp_file ('\n')
- s := String (70 + EstrLen (from))
- IF (alternate_cmd)
- DisposeLink (s)
- s := generate_alternate_cmd ('AList', 'AList Mailing List Server', 'Re: Your command(s)', from)
- ELSEIF (no_from)
- StringF (s, '-R "AList Mailing List Server" -s "Re: Your command(s)" -t "\s"', from)
- ELSE
- StringF (s, '-f AList -R "AList Mailing List Server" -s "Re: Your command(s)" -t "\s"', from)
- ENDIF
- send_message (s)
- DisposeLink (s)
- ENDPROC
-
-
- /*
- * Checks to see if a string contains anything
- */
- PROC is_empty (str)
- IF (str = NIL) THEN RETURN TRUE
- str := TrimStr (str)
- IF (str[0]) THEN RETURN FALSE ELSE RETURN TRUE
- ENDPROC
-
-
- /*
- * Returns the address of the first whitespace (<33) in the string, or NIL
- */
- PROC find_empty (str:PTR TO CHAR)
- DEF x
-
- IF (str = NIL) THEN RETURN NIL
- x := 0
- WHILE (str[x] > 32)
- INC x
- ENDWHILE
-
- IF (str[x]) THEN RETURN str+x
- ENDPROC NIL
-
-
- /*
- * Adds a user to a list.
- */
- PROC add_user (name:PTR TO CHAR, listname:PTR TO CHAR)
- DEF s:PTR TO CHAR, list:PTR TO config_node
-
- IF (IF (listname[0]) THEN ((list := find_list (listname)) = NIL) ELSE TRUE)
- add_tmp_file ('Unknown list "')
- add_tmp_file (listname)
- add_tmp_file ('".\nFor a list of known lists, use the INDEX command.\n')
- RETURN
- ENDIF
-
- /* Do all tests for permissions to add this user here */
-
- IF (on_list (name, list.users, (list.flags AND CNF_CMP_DOMAIN)))
- add_tmp_file ('User "')
- add_tmp_file (name)
- add_tmp_file ('" is already subscribed to that list.\n')
- RETURN
- ENDIF
-
- s := String (EstrLen (name))
- StrCopy (s, name)
- list.users := add_link (list.users, s)
- add_tmp_file ('User "')
- add_tmp_file (s)
- add_tmp_file ('" has been added to the list "')
- add_tmp_file (list.name)
- add_tmp_file ('".\n')
- /* Should really add a post to the owner as well here */
-
- /* Now, write out the file */
- IF (write_user_list (list) = FALSE)
- add_tmp_file ('WARNING: Unable to write user list! Inform the owner immediately!\n')
- ELSE
- send_list_welcome (name, list)
- ENDIF
- ENDPROC
-
-
- /*
- * Send off the welcome message to the new user on the list.
- */
- PROC send_list_welcome (name:PTR TO CHAR, list:PTR TO config_node)
- DEF s:PTR TO CHAR, tmp2_file:PTR TO CHAR, tmp_s:PTR TO CHAR
- DEF tmp2_s:PTR TO CHAR
-
- /* Move tmp to tmp2 file */
- tmp2_file := temp_file
- temp_file := String (EstrLen (tmp2_file) + 2)
- StrCopy (temp_file, tmp2_file)
- StrAdd (temp_file, 'a')
- clear_tmp_file()
-
- /* Write List Welcome HERE */
- IF (no_from OR alternate_cmd)
- add_tmp_file ('From: ')
- add_tmp_file (list.name)
- add_tmp_file ('-list-owner@')
- add_tmp_file (hostname)
- add_tmp_file ('\n\n')
- ENDIF
-
- add_tmp_file ('\nWELCOME!\n\nA message from the AList Email server:\n')
- add_tmp_file ('You may unsubscribe at any time by sending a message to\n AList@')
- add_tmp_file (hostname)
- add_tmp_file ('\nwith a line in the body that reads:\nUNSUBSCRIBE ')
- add_tmp_file (list.name)
- add_tmp_file ('\n\nFor a complete listing of commands the AList server accepts,\n')
- add_tmp_file ('send a message with a line containing only the word HELP.\n\n')
-
- IF (list.welcome)
- /* Tack onto the end */
- add_tmp_file (list.welcome)
- ENDIF
-
- s := String (113 + (2 * EstrLen (list.name)) + EstrLen (name))
- IF (alternate_cmd)
- tmp_s := s
- StringF (tmp_s, '\s-list-owner', list.name)
- tmp2_s := String (EstrLen (list.name) + 31)
- StringF (tmp2_s, 'Welcome to the \s mailing list!', list.name)
- s := generate_alternate_cmd (tmp_s, 'AList Mailing List Server', tmp2_s, name)
- DisposeLink (tmp_s)
- DisposeLink (tmp2_s)
- ELSEIF (no_from)
- StringF (s,
- '-R "AList Mailing List Server" -s "Welcome to the \s mailing list!" -t "\s"',
- list.name, name)
- ELSE
- StringF (s,
- '-f \s-list-owner -R "AList Mailing List Server" -s "Welcome to the \s mailing list!" -t "\s"',
- list.name, list.name, name)
- ENDIF
-
- send_message (s)
- DisposeLink (s)
-
- /* Move tmp2 back to tmp */
- DisposeLink (temp_file)
- temp_file := tmp2_file
- ENDPROC
-
-
- /*
- * Removes a user from a list
- */
- PROC remove_user (name:PTR TO CHAR, listname:PTR TO CHAR)
- DEF s:PTR TO CHAR, list:PTR TO config_node, s2:PTR TO CHAR
-
- IF (IF (listname[0]) THEN ((list := find_list (listname)) = NIL) ELSE TRUE)
- add_tmp_file ('Unknown list "')
- add_tmp_file (listname)
- add_tmp_file ('".\nFor a list of known lists, use the INDEX command.\n')
- RETURN
- ENDIF
-
- /* Do all tests for permissions to remove this user here */
-
- IF ((s := on_list (name, list.users, (list.flags AND CNF_CMP_DOMAIN))) = NIL)
- add_tmp_file ('User "')
- add_tmp_file (name)
- add_tmp_file ('" is not subscribed to that list.\n')
- RETURN
- ENDIF
-
- s2 := list.users
- IF (s2 = s) /* Whoops, removing the head, special case... */
- list.users := Next(s)
- Link (s, NIL)
- DisposeLink (s)
- ELSE
- /* s will still be on from the users list, so no need for NIL checking */
- WHILE (Next (s2) <> s) /* Note that we don't need to StrCmp here */
- s2 := Next (s2)
- ENDWHILE
- /* Now, we have the one before it */
- Link (s2, Next(s))
- Link (s, NIL)
- DisposeLink (s)
- ENDIF
-
- add_tmp_file ('User "')
- add_tmp_file (s)
- add_tmp_file ('" has been removed from the list "')
- add_tmp_file (list.name)
- add_tmp_file ('".\n')
- /* Should really add a post to the owner as well here */
-
- /* Now write out the user list */
- IF (write_user_list (list) = FALSE)
- add_tmp_file ('WARNING: Unable to write user list! Inform the owner immediately!\n')
- ENDIF
- ENDPROC
-
-
- /*
- * Fills the 2 defaults with the arguments, if there. Otherwise, leaves them be.
- *
- * Requires def1 and def2 to be valid buffers (e strings).
- */
- PROC get_cmd_args (str, def1:PTR TO CHAR, def2:PTR TO CHAR)
- DEF x, y
-
- x := 0
- WHILE (str[x] < 33) AND (str[x] > 0)
- INC x
- ENDWHILE
- y := x
- WHILE (str[x] > 32)
- INC x
- ENDWHILE
- IF (x > y)
- StrCopy (def1, str+y, x-y)
- WHILE (str[x] < 33) AND (str[x] > 0)
- INC x
- ENDWHILE
- y := x
- WHILE (str[x] > 32)
- INC x
- ENDWHILE
- IF (x > y)
- StrCopy (def2, str+y, x-y)
- ENDIF
- ENDIF
- ENDPROC
-
-
-